import DataTable, { HFColumns } from '@/components/DataTable'
import { getDistinct } from '@/types/request';
import { PermissionField, Role } from '@/types/structs';
import { del, post, postGet, put } from '@/useHttp';
import { ModalForm, ProFormDependency, ProFormSelect, ProFormText, ProTable } from '@ant-design/pro-components';
import { history } from '@umijs/max';
import { Button, notification, Popconfirm, Table } from 'antd';
import React, { useState } from 'react'

const RolePage: React.FC = () => {
  const url = '/api/Role'; // 增删改查接口
  // 类型 T 融合 Role 与 Permissions []Permission
  type T = Role & { Permissions: PermissionField[] };
  // type T = Role; // 数据类型
  // 列定义
  const columns: HFColumns[] = [
    {
      title: '拥有者',
      key: 'owner',
      dataIndex: 'owner',
      valueType: 'text',
      editable: false,
      search: false,
    },
    {
      title: '名称',
      key: 'name',
      dataIndex: 'name',
      valueType: 'select',
      request: async () => getDistinct('Role', 'name', 'displayName'),
      editType: 'text',
    },
    {
      title: '显示名称',
      key: 'displayName',
      dataIndex: 'displayName',
      valueType: 'text',
    },
    {
      title: '启用状态',
      key: 'isEnabled',
      dataIndex: 'isEnabled',
      valueType: 'switch',
    },
    {
      title: '描述',
      key: 'description',
      dataIndex: 'description',
      valueType: 'text',
      editable: false,
    },
    {
      title: '用户',
      key: 'users',
      dataIndex: 'users',
      valueType: 'select',
      editable: false,
      request: () => getDistinct('UserInfo', 'name', 'displayName'),
    },
    {
      title: '创建时间',
      key: 'createdTime',
      dataIndex: 'createdTime',
      valueType: 'dateTime',
      editable: false,
      search: false,
    },
  ]

  // 所有权限
  const [permissionsNone, setPermissionsNone] = useState([] as PermissionField[]);

  return (
    <>
      <DataTable
        url={url}
        columns={columns}
        rowKey={'name'}
        fieldProps={{
          expandable: {
            expandedRowRender: (record: T) => {
              record.Permissions = record.Permissions || []
              // 添加权限
              const handleAddPermission = async (values: any) => {
                // 找到未绑定权限中待定的权限
                const newPermision = permissionsNone.filter((item) => item.App = values.app).filter((item) => item.URL = values.url).filter((item) => item.Action = values.action)[0]

                // 选定的权限绑定到角色
                record.Permissions.push(newPermision)

                // 更新后台数据库
                const { success } = await post<{ success: boolean }>('/api/Policy',
                  { role: record.name, permissionID: [newPermision.UUID] })
                if (success) {
                  notification.success({ message: '添加成功' })
                  history.push('/CAS/role') // 强制刷新
                  return true
                }
                return false
              };

              return (
                <>
                  {/* 使用 DataTable 会提示访问本页面, 但返回 404, 原因未知 */}
                  <ProTable key={record.name}
                    columns={[
                      {
                        title: '应用',
                        dataIndex: 'App',
                      },
                      {
                        title: 'URL',
                        dataIndex: 'URL',
                      },
                      {
                        title: '操作',
                        key: 'Action',
                        dataIndex: 'Action',
                      },
                      {
                        title: '启用状态',
                        key: 'Enable',
                        dataIndex: 'Enable',
                      },
                      {
                        title: '备注',
                        key: 'Remark',
                        dataIndex: 'Remark',
                      },
                      {
                        title: '操作',
                        valueType: 'option',
                        key: 'option',
                        render: (_, permission, index, action) => [
                          <Popconfirm
                            title="确定要删除吗?"
                            onConfirm={async () => {
                              const { success } = await del<{ success: boolean }>('/api/Policy', { role: record.name, permissionID: permission.UUID })
                              if (!success) return false
                              record.Permissions = record.Permissions.filter((item: PermissionField) => item.UUID !== permission.UUID);
                              // (parentActionRef.current as any).reload() // 无效
                              history.push('/CAS/role') // 强制刷新
                              return true
                            }}
                            okText="确定"
                            cancelText="取消"
                          >
                            <a key={index} >删除</a>
                          </Popconfirm>
                        ],
                      },
                    ]}

                    dataSource={record.Permissions} rowKey={'UUID'}
                    search={false}
                    toolBarRender={false}
                    pagination={false}
                  />
                  <ModalForm
                    title="添加权限"
                    trigger={<Button type={'primary'}>添加权限</Button>}
                    clearOnDestroy={true}
                    modalProps={{
                      destroyOnClose: true,
                    }}
                    onFinish={handleAddPermission}
                    onOpenChange={async (visible) => {
                      if (visible) {
                        // 获取权限, 排除绑定的权限
                        const { success, data } = await postGet<{ success: boolean, data: PermissionField[] }>('/api/get/Permission', record.Permissions && record.Permissions.length > 0 ? { 'UUID': { 'not in': record.Permissions.map((item: PermissionField) => item.UUID) } } : {})
                        if (!success) return false
                        setPermissionsNone(data)
                      }
                    }}
                  >
                    {/* 取策略, 不包括 record.Permissions */}
                    <ProFormSelect
                      name="app"
                      label="应用"
                      options={
                        // 从 permissionsNone 中取 app, 相同 app 只取一个
                        Array.from(new Set(permissionsNone.length > 0 ? permissionsNone.map((item: PermissionField) => item.App) : []))
                          .map((item: string) => ({
                            value: item,
                            label: item,
                          }))
                      }
                    />
                    {/* 将 app 中绑定的数据传递到下来,并使用 ProFormDependency 实现, 选择 app后联动 url 和 action的值到 url 和 action */}
                    <ProFormDependency name={['app']}>
                      {({ app }) => {
                        if (app) {
                          return (
                            <>
                              <ProFormSelect
                                name="url"
                                label="URL"
                                options={
                                  // 从 app 绑定的数据中 取 url
                                  (Array.from(new Set(permissionsNone.filter((item: any) => item.App === app)
                                    .map((item: any) => item.URL))).map((item: string) => ({
                                      value: item,
                                      label: item,
                                    })))
                                }
                              />
                            </>
                          )
                        }
                      }}
                    </ProFormDependency>
                    {/* 使用 ProFormDependency 实现, 选择 app 和 url 后, 获取 action的值到 action */}
                    <ProFormDependency name={['app', 'url']}>
                      {({ app, url }) => {
                        if (app && url) {
                          return (
                            <>
                              <ProFormSelect
                                name="action"
                                label="操作"
                                request={async () => {
                                  // 从 app 绑定的数据中 取 action
                                  return permissionsNone.filter((item: any) => item.App === app && item.URL === url).map((item: any) => ({
                                    value: item.Action,
                                    label: item.Action,
                                  }))
                                }}
                              />
                            </>
                          )
                        }
                      }}
                    </ProFormDependency>
                  </ModalForm>
                </>
              );
            }
          }
        }}

        extractAction={(_, entity: T, index, action): React.ReactNode[] => {
          return [
            <a key={'role' + index} >
              <ModalForm title="添加用户到角色" trigger={<Button type={'primary'} >用户</Button>}
                clearOnDestroy={true}
                onFinish={async (values) => {
                  // 比较 entity.users 和 values.users, 如果有新增的，则添加, 如果有删除的，则删除
                  const newUsers = values.users.filter((v: string) => !entity.users.includes(v))
                  if (newUsers.length > 0) {
                    const { success } = await post<{ success: boolean }>('/api/addUserToRole',
                      { role: entity.name, users: newUsers })
                    if (success) {
                      notification.success({ message: '添加成功' })
                      action.reload();
                    }
                  }
                  // 移除用户
                  const delUsers = entity.users.filter(item => !values.users.includes(item))
                  if (delUsers.length > 0) {
                    const { success } = await post<{ success: boolean }>('/api/removeUserFromRole',
                      { role: entity.name, users: delUsers })
                    if (success) {
                      notification.success({ message: '移除成功' })
                      action.reload();
                    }
                  }
                  return true // 自动关闭
                }}
              >
                <ProFormText name="name" label="角色" readonly={true} initialValue={entity.name} />
                <ProFormSelect name="users" label="用户" showSearch allowClear={true}
                  mode="multiple" initialValue={entity.users}
                  request={async () => getDistinct('UserInfo', 'name', 'displayName')}
                />
              </ModalForm>
            </a >
          ];
        }}
        // hideAction={true} // 隐藏操作列
        // hideDeleteButton={true} // 隐藏操作列中的删除按钮
        hideEditButton={true} // 隐藏操作列中的编辑按钮

      // showSearchBox={false} // 隐藏搜索框
      // hideToolbar={true} // 隐藏工具栏(新增,刷新)
      // hidePagination={true} // 隐藏底部分页项
      />
    </>
  )
}

export default RolePage